/*
package com.jml.jdk8.stream;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.ObjIntConsumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collector;
import java.util.stream.Collector.Characteristics;
import java.util.stream.Collectors;
import java.util.stream.Collectors.CollectorImpl;
import java.util.stream.Collectors.Partition;

*/
/**
 * @author:jml
 * @date: 2020/2/24 0024 23:00
 * @description：
 *//*

public class GroupBy源码解析 {

    static class CollectorImpl<T, A, R> implements Collector<T, A, R> {

        private final Supplier<A> supplier;
        private final BiConsumer<A, T> accumulator;
        private final BinaryOperator<A> combiner;
        private final Function<A, R> finisher;
        private final Set<Characteristics> characteristics;

        CollectorImpl(Supplier<A> supplier,
                BiConsumer<A, T> accumulator,
                BinaryOperator<A> combiner,
                Function<A, R> finisher,
                Set<Characteristics> characteristics) {
            this.supplier = supplier;
            this.accumulator = accumulator;
            this.combiner = combiner;
            this.finisher = finisher;
            this.characteristics = characteristics;
        }

        CollectorImpl(Supplier<A> supplier,
                BiConsumer<A, T> accumulator,
                BinaryOperator<A> combiner,
                Set<Characteristics> characteristics) {
            this(supplier, accumulator, combiner, castingIdentity(), characteristics);
        }

        @Override
        public Supplier<A> supplier() {
            return null;
        }

        @Override
        public BiConsumer<A, T> accumulator() {
            return null;
        }

        @Override
        public BinaryOperator<A> combiner() {
            return null;
        }

        @Override
        public Function<A, R> finisher() {
            return null;
        }

        @Override
        public Set<Characteristics> characteristics() {
            return null;
        }
    }

    public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>(
                (Supplier<List<T>>) ArrayList::new, //supplier
                List::add,                          //accumulator
                (left, right) -> { left.addAll(right); return left; },//combiner
                CH_ID);
    }

    Map<Integer, List<Student>> scoreMap = students.stream()
            .collect(Collectors.groupingBy(s -> s.getName()));

    public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier) {
        return groupingBy(classifier, toList());
    }

    public static <T, K, A, D>
    Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
            Collector<? super T, A, D> downstream) {
        return groupingBy(classifier, HashMap::new, downstream);
    }



    public static <T, K, D, A, M extends Map<K, D>>
    Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,
            Supplier<M> mapFactory,
            Collector<? super T, A, D> downstream) {
        Supplier<A> downstreamSupplier = downstream.supplier();//(Supplier<List<T>>) ArrayList::new,
        BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();//List::add,
        //把key全部放入list中，  Map<K, A>在这里设置为中间结果类型，A在这里是个List
        BiConsumer<Map<K, A>, T> accumulator = (m, t) -> {
            //s -> s.getName()  key就是name，String
            K key = Objects.requireNonNull(classifier.apply(t), "element cannot be mapped to a null key");
            //在Map<K, A>中一个key对应一个List，
            // 如果Key对应的value是Null，就新建一个List构建成key-List放入Map中，然后返回key对应的这个List，
            // container 就是List ，downstreamSupplier.get()就是(Supplier<List<T>>) ArrayList::new
            A container = m.computeIfAbsent(key, k -> downstreamSupplier.get());
            //List::add,把传入的参数全部放入list中
            //如果groupingByConcurrent的downstream的Characteristics没有CONCURRENT，
            //groupingByConcurrent在这里加了synchonize锁，防止并发
            */
/*synchronized (resultContainer) {
                downstreamAccumulator.accept(resultContainer, t);
            }*//*

            downstreamAccumulator.accept(container, t);
        };
        //两个Map的合并
        //downstream.combiner()就是(left, right) -> { left.addAll(right); return left; },
        BinaryOperator<Map<K, A>> merger = Collectors.<K, A, Map<K, A>>mapMerger(downstream.combiner());
        @SuppressWarnings("unchecked")
        //M 强转转换为 Map<K, A> ，M本身就是Map<Object,Object>
        Supplier<Map<K, A>> mangledFactory = (Supplier<Map<K, A>>) mapFactory;
        if (downstream.characteristics().contains(Characteristics.IDENTITY_FINISH)) {
            return new Collectors.CollectorImpl<>(mangledFactory, accumulator, merger, CH_ID);
        }
        else {
            @SuppressWarnings("unchecked")
            Function<A, A> downstreamFinisher = (Function<A, A>) downstream.finisher();
            Function<Map<K, A>, M> finisher = intermediate -> {
                //设置value，修改map的value
                intermediate.replaceAll((k, v) -> downstreamFinisher.apply(v));
                @SuppressWarnings("unchecked")
                M castResult = (M) intermediate;
                return castResult;
            };
            return new Collectors.CollectorImpl<>(mangledFactory, accumulator, merger, finisher, CH_NOID);
        }
    }


    public static <T>
    Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) {
        return partitioningBy(predicate, toList());
    }

    public static <T, D, A>
    Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate,
            Collector<? super T, A, D> downstream) {

        BiConsumer<List<Integer>, Integer> listIntegerBiConsumer = (List<Integer> a, Integer b) -> {
            a.add(b);
        };

        BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
        BiConsumer<Partition<A>, T> accumulator = (result, t) ->
                downstreamAccumulator.accept(predicate.test(t) ? result.forTrue : result.forFalse, t);
        BinaryOperator<A> op = downstream.combiner();
        BinaryOperator<Partition<A>> merger = (left, right) ->
                new Partition<>(op.apply(left.forTrue, right.forTrue),
                        op.apply(left.forFalse, right.forFalse));
        Supplier<Partition<A>> supplier = () ->
                new Partition<>(downstream.supplier().get(),
                        downstream.supplier().get());
        if (downstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
            return new Collectors.CollectorImpl<>(supplier, accumulator, merger, CH_ID);
        }
        else {
            Function<Partition<A>, Map<Boolean, D>> finisher = par ->
                    new Partition<>(downstream.finisher().apply(par.forTrue),
                            downstream.finisher().apply(par.forFalse));
            return new Collectors.CollectorImpl<>(supplier, accumulator, merger, finisher, CH_NOID);
        }
    }

}




*/
